home *** CD-ROM | disk | FTP | other *** search
- /*
- ==============================================================================
- WordUp Graphics Toolkit Version 5.0
- Demonstration Program 56
-
- This program uses the scrolling library to create a parallax scrolling
- world with two layers. There are three kinds of objects in the world;
- clouds, yellow balls (wearing shades) that move behind the front layer,
- and yellow balls that move in front. Use the arrow keys to move around
- and ESC will exit.
-
- *** PROJECT ***
- This program requires the files WGT5_WC.LIB and WSCR_WC.LIB to be linked.
-
- *** DATA FILES ***
- PARABACK.SPR, PARAFRON.SPR, PARASPR.SPR, PARAMAPB.WMP, PARAMAPF.WMP
- WATCOM C++ VERSION
- ==============================================================================
- */
-
- #include <stdlib.h>
- #include <dos.h>
- #include <wgt5.h>
- #include <wgtscrol.h>
-
-
- #define WIND_SIZEX 20 /* Set scrolling window dimensions (in tiles) */
- #define WIND_SIZEY 13
-
- #define SPEED 8 /* Speed of scrolling */
-
- #define LEFT 75 /* Keyboard codes */
- #define RIGHT 77
- #define UP 72
- #define DOWN 80
- #define ESC 1
- #define KEY_S 31
- #define KEY_L 38
-
-
- #define BACKWIN 0 /* The NORMAL layer */
- #define FRONTWIN 1 /* The PARALLAX layer */
-
- block backtiles[256]; /* Tiles, objects and tiles types for the */
- scrollsprite backobject[200]; /* background window. */
- short backtypes[256];
-
- block fronttiles[256]; /* Tiles, objects and tiles types for the */
- scrollsprite frontobject[200]; /* foreground window. */
- short fronttypes[256];
-
- block sprites[50]; /* The sprite images */
-
- int timer; /* Counts timer ticks */
-
- color pal[256];
-
- short movex, movey; /* Amount to scroll the front */
- short bmovex, bmovey; /* Amount to scroll the back */
-
- short x, y; /* Current viewing coordinates */
- /* The window tries to center itself on
- this coordinate. */
-
- short num_clouds; /* Number of cloud sprites on background */
- short num_ball_behind; /* Number of yellow balls behind front layer.
- All yellow balls with object numbers 100-199 are
- drawn between the background and foreground
- layers. */
- short num_ball_infront; /* Number of yellow balls in front of every layer */
-
- short cloud_speed[100]; /* Movement speed and direction for clouds */
-
- short oldmode; /* Old video mode */
-
- wgtmap backmap; /* Holds the scrolling map */
- wgtmap frontmap; /* Holds the scrolling map */
-
-
- void find_sprites (void)
- /* Searches for the maximum object numbers for each of the three categories
- of wobjects. (clouds, ball behind, ball in front) */
- {
- short i;
-
- num_clouds = 0;
- for (i = 0; i < 100; i++)
- if (backobject[i].on)
- num_clouds = i;
-
- num_ball_behind = 0;
- for (i = 100; i < 200; i++)
- if (frontobject[i].on)
- num_ball_behind = i;
-
- num_ball_infront = 0;
- for (i = 0; i < 100; i++)
- if (frontobject[i].on)
- num_ball_infront = i;
- }
-
-
- void set_cloud_movements (void)
- /* Sets up the movement and speed for clouds */
- {
- short i;
-
- for (i = 0; i < num_clouds; i++)
- {
- cloud_speed[i] = (rand () % 6)-3;
- if (cloud_speed[i] == 0)
- cloud_speed[i] = 1;
- }
- }
-
-
- void move_clouds (scrollsprite *s)
- /* Moves the clouds and wraps them around the map if needed */
- {
- short i;
- short maxx;
-
- maxx = mapwidth[BACKWIN] * tilewidth[BACKWIN];
-
- for (i = 0; i < num_clouds; i++)
- {
- backobject[i].x += cloud_speed[i];
- if (backobject[i].x < -80)
- backobject[i].x = maxx;
- else if (backobject[i].x > maxx)
- backobject[i].x = -80;
- }
- }
-
-
- void move_balls (void)
- /* Moves the balls around randomly */
- {
- short i;
- short maxx, maxy;
-
- maxx = mapwidth[BACKWIN] * tilewidth[BACKWIN];
- maxy = mapheight[BACKWIN] * tileheight[BACKWIN];
-
- for (i = 0; i <= num_ball_infront; i++)
- {
- frontobject[i].x += (rand () % 17) - 8; /* Randomly move the ball */
- frontobject[i].y += (rand () % 17) - 8;
-
- if (frontobject[i].x < 0) /* Check the X boundaries */
- frontobject[i].x = 0;
- else if (frontobject[i].x > maxx)
- frontobject[i].x = maxx;
-
- if (frontobject[i].y < 0) /* Check the Y boundaries */
- frontobject[i].y = 0;
- else if (frontobject[i].y > maxy)
- frontobject[i].y = maxy;
- }
-
- for (i = 100; i <= num_ball_behind; i++)
- /* Do the same with the balls behind the front layer. */
- {
- frontobject[i].x += (rand () % 17) - 8;
- frontobject[i].y += (rand () % 17) - 8;
-
- if (frontobject[i].x < 0)
- frontobject[i].x = 0;
- else if (frontobject[i].x > maxx)
- frontobject[i].x = maxx;
- if (frontobject[i].y < 0)
- frontobject[i].y = 0;
- else if (frontobject[i].y > maxy)
- frontobject[i].y = maxy;
- }
- }
-
-
- void timerctr (void)
- {
- timer++;
- }
-
-
- void main (void)
- {
- float seconds, fps;
- int frames = 0;
-
- oldmode = wgetmode ();
- if (!vgadetected ())
- {
- printf ("VGA is required to run this program...");
- exit (1);
- }
- printf ("WGT Example #56\n\n");
-
- printf ("This program uses the scrolling library to create a parallax scrolling\n");
- printf ("world with two layers. There are three kinds of objects in the world\n");
- printf ("clouds, yellow balls (wearing shades) that move behind the front layer,\n");
- printf ("and yellow balls that move in front. Use the arrow keys to move around\n");
- printf ("and ESC will exit.\n");
- printf ("You can also save and load the map by pressing S and L.\n");
- printf ("\nPress any key to begin\n");
- getch ();
-
-
- vga256 ();
-
- wloadsprites (pal, "paraspr.spr", sprites, 0, 49);
-
- wloadsprites (pal, "paraback.spr", backtiles, 0, 255);
- wloadsprites (pal, "parafron.spr", fronttiles, 0, 255);
- wsetpalette (0, 255, pal);
-
- winitscroll (BACKWIN, NORMAL, 0, WIND_SIZEX / 2, WIND_SIZEY / 2, backtiles);
- /* Uses half the size since the background tiles are twice as big (32x32) */
-
- winitscroll (FRONTWIN, PARALLAX, BACKWIN, WIND_SIZEX, WIND_SIZEY, fronttiles);
- /* Link this window to the background one */
-
- backmap = wloadmap (BACKWIN, "paramapb.wmp", backtypes, backobject);
- frontmap = wloadmap (FRONTWIN, "paramapf.wmp", fronttypes, frontobject);
- /* Load the maps in for both windows */
-
- wshowwindow (BACKWIN, 0, 0);
- wshowwindow (FRONTWIN, 0, 0);
- /* Set the initial viewing coordinates. */
-
- find_sprites ();
- set_cloud_movements ();
-
- installkbd (); /* Install the custom keyboard handler */
- timer = 0;
- winittimer ();
- wstarttimer (timerctr, TICKS(70));
- do {
- move_clouds (backobject);
- move_balls ();
-
- if (kbdon[LEFT]) /* Change the viewing coordinates */
- {
- x -= 8;
- if (x < 0)
- x = 0;
- }
- if (kbdon[RIGHT])
- {
- x += 8;
- if (x > worldmaxx[FRONTWIN])
- x = worldmaxx[FRONTWIN];
- }
- if (kbdon[UP])
- {
- y -= 8;
- if (y < 0)
- y = 0;
- }
- if (kbdon[DOWN])
- {
- y += 8;
- if (y > worldmaxy[FRONTWIN])
- y = worldmaxy[FRONTWIN];
- }
-
- /* Move the foreground by finding the difference between the actual
- world coordinates and the desired world coordinates. This will
- make sure the window is centered on the (x,y) coordinate. */
- movex = x - worldx[FRONTWIN];
- movey = y - worldy[FRONTWIN];
-
- bmovex = worldx[FRONTWIN] + movex;
- bmovey = worldy[FRONTWIN] + movey;
- /* World coordinates of the front windows, after the current move */
-
- /* We must 'clip' them */
- if (bmovex < 0)
- bmovex = 0;
- if (bmovey < 0)
- bmovey = 0;
- if (bmovex > worldmaxx[FRONTWIN] - 1)
- bmovex = worldmaxx[FRONTWIN] - 1;
- if (bmovey > worldmaxy[FRONTWIN] - 1)
- bmovey = worldmaxy[FRONTWIN] - 1;
-
- /* Now make the background coordinates a percentage of the front window */
- bmovex = bmovex * 4 / 5;
- bmovey = bmovey * 9 / 10;
-
- worldx[BACKWIN] = bmovex;
- worldy[BACKWIN] = bmovey;
- /* Set the new background window coordinates */
-
- wscrollwindow (BACKWIN, 0, 0);
- /* Display the background layer. (Layers are drawn from back to front.) */
- /* No need to scroll by a value, because we already moved it by
- changing worldx and worldy */
-
-
- wshowobjects(BACKWIN, 0, num_clouds, sprites, backobject);
- /* Show the clouds next */
-
- wshowobjects(BACKWIN, 100, num_ball_behind, sprites, frontobject);
- /* Show the balls that are behind the front layer. (They will be just in
- front of the clouds) */
-
- wscrollwindow (FRONTWIN, movex, movey);
- /* Display the foreground layer */
-
- wshowobjects(FRONTWIN, 0, num_ball_infront, sprites, frontobject);
- /* Show the balls that are in front of everything else. */
-
- wnormscreen ();
- /* Uncomment the following line to time with the vertical retrace */
- // wretrace();
- wputblock (0, 0, scrollblock[BACKWIN], 0);
- /* Once the image is built, display the whole thing on the visual screen. */
-
- if (kbdon[KEY_S]) /* Save the map */
- {
- while (kbdon[KEY_S] == 1)
- wretrace (); /* Wait until the user releases the S key */
- wsavemap (FRONTWIN, "savefron.wmp", frontmap, fronttypes, frontobject, num_ball_behind+1);
- wsavemap (BACKWIN, "saveback.wmp", backmap, backtypes, backobject, num_clouds+1);
- }
- if (kbdon[KEY_L]) /* Load the map */
- {
- while (kbdon[KEY_L])
- wretrace (); /* Wait until the user releases the L key */
- wfreemap (frontmap); /* Free the maps that are already in memory */
- wfreemap (backmap);
- frontmap = wloadmap (FRONTWIN, "savefron.wmp", fronttypes, frontobject);
- backmap = wloadmap (BACKWIN, "saveback.wmp", backtypes, backobject);
- }
- frames++;
- } while (kbdon[ESC] == 0);
- wstoptimer ();
- wdonetimer ();
-
- /* Now clean up everything */
- wendscroll (FRONTWIN);
- wendscroll (BACKWIN);
-
- uninstallkbd ();
- wfreesprites (fronttiles, 0, 255);
- wfreesprites (backtiles, 0, 255);
- wfreesprites (sprites, 0, 49);
- wfreemap (backmap);
- wfreemap (frontmap);
- wsetmode (oldmode);
- seconds = (float)(timer / 70.0);
- fps = (float)(frames) / seconds;
- printf ("Frames completed: %d\n", frames);
- printf ("Seconds elapsed: %g\n", seconds);
- printf ("FPS: %g\n", fps);
- }
-